package crud

import (
	"context"
	"fmt"
	"strings"

	"github.com/zeromicro/go-zero/core/stores/cache"
	"github.com/zeromicro/go-zero/core/stores/sqlx"
)

var _ RolePermissionsModel = (*customRolePermissionsModel)(nil)

type (
	// RolePermissionsModel is an interface to be customized, add more methods here,
	// and implement the added methods in customRolePermissionsModel.
	RolePermissionsModel interface {
		rolePermissionsModel
		DeleteByRoleId(ctx context.Context, roleId int64) error
		BatchInsert(ctx context.Context, data []*RolePermissions) error
		FindPermissionIdsByRoleId(ctx context.Context, roleId int64) ([]int64, error)
	}

	customRolePermissionsModel struct {
		*defaultRolePermissionsModel
	}
)

// NewRolePermissionsModel returns a model for the database table.
func NewRolePermissionsModel(conn sqlx.SqlConn, c cache.CacheConf, opts ...cache.Option) RolePermissionsModel {
	return &customRolePermissionsModel{
		defaultRolePermissionsModel: newRolePermissionsModel(conn, c, opts...),
	}
}

// DeleteByRoleId deletes role permissions by role id.
func (m *customRolePermissionsModel) DeleteByRoleId(ctx context.Context, roleId int64) error {
	query := fmt.Sprintf("delete from %s where `role_id` = ?", m.table)
	_, err := m.ExecNoCacheCtx(ctx, query, roleId)
	return err
}

// BatchInsert inserts multiple role permissions.
func (m *customRolePermissionsModel) BatchInsert(ctx context.Context, data []*RolePermissions) error {
	if len(data) == 0 {
		return nil
	}

	query := fmt.Sprintf("insert into %s (%s) values ", m.table, rolePermissionsRowsExpectAutoSet)
	var args []interface{}
	var placeholders []string
	for _, item := range data {
		placeholders = append(placeholders, "(?, ?)")
		args = append(args, item.RoleId, item.PermissionId)
	}
	query += strings.Join(placeholders, ", ")

	_, err := m.ExecNoCacheCtx(ctx, query, args...)
	return err
}

// FindPermissionIdsByRoleId finds permission ids by role id.
func (m *customRolePermissionsModel) FindPermissionIdsByRoleId(ctx context.Context, roleId int64) ([]int64, error) {
	query := fmt.Sprintf("select `permission_id` from %s where `role_id` = ?", m.table)
	var resp []int64
	err := m.QueryRowsNoCacheCtx(ctx, &resp, query, roleId)
	return resp, err
}
